<?php

namespace Cframe\methods;


abstract class SqlMethod {
    protected static $table = '';
    protected static $condition = '';
    protected static $sql = '';
    protected static $field = '*';
    protected static $prefix = '';
    // 生成替换区

    public function table($tbname,$alise = ''){
        if (empty($alise)){
            if (strstr($tbname,' ')){
                $tb = explode(" ",$tbname);
                $tb[0] = "`{$tb[0]}`";
                $alise = $tb[1];
                $str = implode(" ",$tb);
            }else{
                $str = "`{$tbname}`";
            }
        }else{

            $str = "`{$tbname}` {$alise}";
        }
        static::$alise = $alise;
        static::$table = $str;
        return $this;
    }

    public function toEnd($type = "select"){
        switch (strtolower($type)){
            case 'select':
                $sql = "SELECT ".static::$field." FROM ".static::$table . static::$condition;
                break;
            case 'find':
                $sql = "SELECT ".static::$field." FROM ".static::$table . static::$condition;
                $sql = preg_replace('/LIMIT\s+\d+,\d+/i','',$sql)." LIMIT 1";
                break;
            case 'update':
                $sql = "UPDATE ".static::$table ." SET ". static::$data . static::$condition;
                break;
            case 'insert':
                $sql = "INSERT INTO " . static::$table . static::$node." VALUES ".static::$data;
                break;
            case 'delete':
                $sql = "DELETE FROM ". static::$table .static::$condition;
                break;
            default:
                $sql = '';
        }
        static::$sql = $sql;
    }

    public function filed($field = ""){
        if (empty($field)){
            static::$field = '*';
            return false;
        }
        $fields = '';
        if(is_array($field)){
            foreach ($field as $key=>$val){
                if (is_numeric($key)){
                    $fields .= $this->con_field($val) . ',';
                    continue;
                }
                $fields .= $this->con_field($val) . " AS {$val}";
            }
        }else{
            $fields = $this->con_field($field);
        }
        static::$field = $fields;
    }

    public function limit($limit,$count = 1){
        $condition = ' LIMIT ';
        if (is_numeric($limit)){
            $condition .= "{$limit},{$count}";
        }else{
            $condition .= $limit;
        }
        static::$condition .= $condition;
        return $this;
    }

    public function order($order,$asc = 'asc'){
        $condition = ' ORDER BY ';
        $asc = strtoupper($asc);
        if (is_array($order)){
            foreach ($order as $key=>$val){
                if (is_numeric($key)){
                    $condition .= "`{$val}`";
                }elseif (strstr($key,',')){
                    $key = $this->con_field($key);
                    $condition .= "{$key} {$val}";
                    break;
                }

            }
            $condition .= " $asc";
        }else{
            $condition .= $this->con_field($order) . " {$asc}";
        }
        static::$condition .= $condition;
        return $this;
    }

    public function where($name,$value,$judge = 'eq'){
        $condition = ' WHERE ';
        $judge = $this->key_con($judge);
        if (empty($name)){
            static::$condition = '';
            return false;
        }
        if (empty($value)){
            if (is_array($name)){
                $last = end($name);
                foreach ($name as $key=>$val){
                    $key = $this->con_field($key);
                    if (is_array($val)){
                        $val[1] = isset($val[1])?$val[1]:'eq';
                        $val[2] = isset($val[2])?$val[2]:'';
                        $val[3] = isset($val[3])?$val[3]:'AND';
                        $judge = $this->key_con($val[1]);
                        $value = $this->con_string($val[0],false);
                        $keyword = $val[2];
                        switch (strtolower($keyword)){
                            case 'in':
                                $condition .= "{$key} in ({$value})";
                                break;
                            case 'between':
                                $value = implode(' AND ',explode(',',$value));
                                $condition .= "{$key} BETWEEN {$value}";
                                break;
                            default:
                                $condition .= "{$key} {$judge} {$value} {$val[3]} ";
                        }
                    }else{
                        $value = $this->con_string($val,true);
                        if ($val != $last) {
                            $value .= ' AND ';
                        }
                        $condition .= "{$key} {$judge} {$value}";
                    }
                }
            }else{
                static::$condition = '';
            }
        }else{
            $value = $this->con_string($value);
            $name = $key = $this->key_con($name);
            $condition .= "{$name} {$judge} {$value}";
        }
        static::$condition .= $condition;
        return $this;
    }

    // 帮助函数区

    abstract function data();

    public function getLastsql(){
        if (empty(static::$sql)){
            return static::$condition;
        }else{
            return static::$sql;
        }
    }

    private function key_con($str){
        if (empty($str)){
            return $str;
        }
        switch (strtolower($str)){
            case 'eq':
                $str = "=";
                break;
            case 'neq':
                $str = '!=';
                break;
            case 'leq':
                $str = '<=';
                break;
            case 'lt':
                $str = '<';
                break;
            case 'geq':
                $str = '>=';
                break;
            case 'gt':
                $str = '>';
                break;
        }
        return $str;
    }

    private function con_string($str,$auto = false){
        $sign = [',','|'];
        $string = $str;
        foreach ($sign as $k){
            if (strpos($str,$k)){
                $str_a = explode($k,$str);
                array_walk($str_a,function (&$value) use ($auto){
                    if (!is_numeric($value) && !$auto) {
                        $value = "'{$value}'";
                    }
                });
                $str = implode($k,$str_a);
                break;
            }
        }
        if (strcmp($str,$string) == 0){
            return "'{$str}'";
        }
        return $str;
    }

    private function con_field($str,$auto=false){
        $sign = [',','|'];
        $string = $str;
        $alise = empty(!static::$alise) ? static::$alise . '.' : '';
        foreach ($sign as $k){
            if (strpos($str,$k)){
                $str_a = explode($k,$str);
                array_walk($str_a,function (&$value) use ($auto,$alise){
                    if (!is_numeric($value) && !$auto) {
                        $value = "{$alise}`{$value}`";
                    }
                });
                $str = implode($k,$str_a);
                break;
            }
        }
        if (strcmp($str,$string) == 0){
            return "{$alise}`{$str}`";
        }
        return $str;
    }
}